package cn.iocoder.yudao.module.project.controller.admin.order;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.project.controller.admin.kismaterielexwarehouse.vo.CartonCodeDetailNumVO;
import cn.iocoder.yudao.module.project.dal.dataobject.deptcompletedlog.DeptCompletedLogDO;
import cn.iocoder.yudao.module.project.dal.dataobject.dispatchlist.DispatchListDO;
import cn.iocoder.yudao.module.project.dal.dataobject.internalcode.InternalCodeDO;
import cn.iocoder.yudao.module.project.dal.dataobject.kismaterielexwarehouse.KisMaterielExWarehouseDO;
import cn.iocoder.yudao.module.project.dal.dataobject.kismaterielexwarehousehistory.KisMaterielExWarehouseHistoryDO;
import cn.iocoder.yudao.module.project.dal.dataobject.orderdetail.OrderDetailDO;
import cn.iocoder.yudao.module.project.dal.mysql.dispatchlist.DispatchListMapper;
import cn.iocoder.yudao.module.project.dal.mysql.kismaterielexwarehouse.KisMaterielExWarehouseMapper;
import cn.iocoder.yudao.module.project.dal.mysql.kismaterielexwarehousehistory.KisMaterielExWarehouseHistoryMapper;
import cn.iocoder.yudao.module.project.dal.mysql.orderdetail.OrderDetailMapper;
import cn.iocoder.yudao.module.project.service.internalcode.InternalCodeService;
import cn.iocoder.yudao.module.project.service.kismaterielexwarehouse.KisMaterielExWarehouseService;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.*;
import javax.servlet.http.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.module.project.config.projectDefine.HTTP_STATUS.ERROR_STATUS;
import static cn.iocoder.yudao.module.project.config.projectDefine.MATERIAL_STATUS.MATERIAL_STATUS_1;
import static cn.iocoder.yudao.module.project.config.projectDefine.MATERIAL_STATUS.MATERIAL_STATUS_2;
import static cn.iocoder.yudao.module.project.config.projectDefine.ORDER_STATUS.ORDER_STATUS_0;
import static cn.iocoder.yudao.module.project.config.projectDefine.ORDER_STATUS.ORDER_STATUS_2;
import static cn.iocoder.yudao.module.project.config.projectDefine.SERIAL_STR.SERIAL_NUMBER_INIT;
import static cn.iocoder.yudao.module.project.config.projectDefine.SUBMIT_STATUS.SUBMIT_STATUS_0;
import static cn.iocoder.yudao.module.project.config.projectDefine.SUBMIT_STATUS.SUBMIT_STATUS_1;

import cn.iocoder.yudao.module.project.controller.admin.order.vo.*;
import cn.iocoder.yudao.module.project.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.project.service.order.OrderService;

@Tag(name = "管理后台 - 生产订单信息")
@RestController
@RequestMapping("/project/order")
@Validated
public class OrderController {

    @Resource
    private OrderService orderService;

    @Resource
    private InternalCodeService internalCodeService;

    @Resource
    private KisMaterielExWarehouseMapper kisMaterielExWarehouseMapper;

    @Resource
    private OrderDetailMapper orderDetailMapper;

    @Resource
    private KisMaterielExWarehouseService kisMaterielExWarehouseService;

    @Resource
    private KisMaterielExWarehouseHistoryMapper kisMaterielExWarehouseHistoryMapper;

    @Resource
    private DictDataApi dictDataApi;

    @Resource
    private DispatchListMapper dispatchListMapper;

    @PostMapping("/create")
    @Operation(summary = "创建生产订单信息")
    // @PreAuthorize("@ss.hasPermission('project:order:create')")
    public CommonResult<String> createOrder(@Valid @RequestBody OrderSaveReqVO createReqVO) {
        return success(orderService.createOrder(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新生产订单信息")
    // @PreAuthorize("@ss.hasPermission('project:order:update')")
    public CommonResult<Boolean> updateOrder(@Valid @RequestBody OrderSaveReqVO updateReqVO) {
        orderService.updateOrder(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除生产订单信息")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('project:order:delete')")
    public CommonResult<Boolean> deleteOrder(@RequestParam("id") String id) {
        orderService.deleteOrder(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得生产订单信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    // @PreAuthorize("@ss.hasPermission('project:order:query')")
    public CommonResult<OrderRespVO> getOrder(@RequestParam("id") String id) {
        OrderDO order = orderService.getOrder(id);
        return success(BeanUtils.toBean(order, OrderRespVO.class));
    }

    @RequestMapping("/page")
    @Operation(summary = "获得生产订单信息分页")
    @PreAuthorize("@ss.hasPermission('project:order:query')")
    public CommonResult<PageResult<OrderRespVO>> getOrderPage(@Valid @RequestBody OrderPageReqVO pageReqVO) {
        String[] orderDateReq = pageReqVO.getOrderDateReq();
        if (null != orderDateReq && orderDateReq.length == 2) {
            String startTime = orderDateReq[0];
            String endTime = orderDateReq[1];
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                LocalDate startDate = LocalDate.parse(startTime);
                LocalDate endDate = LocalDate.parse(endTime);
                pageReqVO.setStartDate(startDate);
                pageReqVO.setEndDate(endDate);
            }
        }

        PageResult<OrderDO> pageResult = orderService.getOrderPage(pageReqVO);
        PageResult<OrderRespVO> result = BeanUtils.toBean(pageResult, OrderRespVO.class);
        if (null != result) {
            List<OrderRespVO> list = result.getList();
            if (CollectionUtil.isNotEmpty(list)) {
                for (OrderRespVO orderRespVO : list) {
                    LocalDateTime createTime = orderRespVO.getCreateTime();
                    LocalDateTime orderDate = orderRespVO.getOrderDate();
                    String createTimeStr = DateUtil.format(createTime, "yyyy-MM-dd HH:mm:ss");
                    String orderDateStr = DateUtil.format(orderDate, "yyyy-MM-dd");
                    orderRespVO.setCreateTimeStr(createTimeStr);
                    orderRespVO.setOrderDateStr(orderDateStr);
                    if(orderRespVO.getShippingDate() != null){
                        orderRespVO.setShippingDateStr(DateUtil.format(orderRespVO.getShippingDate(), "yyyy-MM-dd"));
                    }
                    //Integer unfinishedNum = orderService.getUnfinishedNum(orderRespVO.getId());
                    //orderRespVO.setUnfinishedNum(unfinishedNum);

                }
            }
        }
        return success(result);
    }

    @RequestMapping("/getOrderAndDispatchList")
    @Operation(summary = "获得生产订单信息分页")
    @PreAuthorize("@ss.hasPermission('project:order:query')")
    public CommonResult<PageResult<OrderRespVO>> getOrderAndDispatchList(@Valid @RequestBody OrderPageReqVO pageReqVO) {
        String[] orderDateReq = pageReqVO.getOrderDateReq();
        if (null != orderDateReq && orderDateReq.length == 2) {
            String startTime = orderDateReq[0];
            String endTime = orderDateReq[1];
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                LocalDate startDate = LocalDate.parse(startTime);
                LocalDate endDate = LocalDate.parse(endTime);
                pageReqVO.setStartDate(startDate);
                pageReqVO.setEndDate(endDate);
            }
        }

        PageResult<OrderRespVO> result = orderService.getOrderAndDispatchList(pageReqVO);
        return success(result);
    }

    @GetMapping("/exportOrderAndDispatchList")
    @Operation(summary = "导出生产订单信息 Excel")
    @ApiAccessLog(operateType = EXPORT)
    public void exportOrderAndDispatchList(@Valid OrderPageReqVO pageReqVO,
                                 HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        String[] orderDateReq = pageReqVO.getOrderDateReq();
        if (null != orderDateReq && orderDateReq.length == 2) {
            String startTime = orderDateReq[0];
            String endTime = orderDateReq[1];
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                LocalDate startDate = LocalDate.parse(startTime);
                LocalDate endDate = LocalDate.parse(endTime);
                pageReqVO.setStartDate(startDate);
                pageReqVO.setEndDate(endDate);
            }
        }

        PageResult<OrderRespVO> result = orderService.getOrderAndDispatchList(pageReqVO);

        List<DictDataRespDTO> statusList = dictDataApi.getDictDataList("order_status");
        Map<String, String> statusMap = statusList.stream().collect(Collectors.toMap(DictDataRespDTO::getValue, DictDataRespDTO::getLabel));

        List<OrderRespVO> orderRespVOList = result.getList();

        for(OrderRespVO respVO : orderRespVOList){
            respVO.setStatusName(statusMap.get(respVO.getStatus()));
        }

        // 导出 Excel
        ExcelUtils.write(response, "生产订单信息.xls", "数据", OrderRespVO.class,
                orderRespVOList);
    }



    @GetMapping("/export-excel")
    @Operation(summary = "导出生产订单信息 Excel")
    // @PreAuthorize("@ss.hasPermission('project:order:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportOrderExcel(@Valid OrderPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<OrderDO> list = orderService.getOrderPage(pageReqVO).getList();

        List<DictDataRespDTO> statusList = dictDataApi.getDictDataList("order_status");
        Map<String, String> statusMap = statusList.stream().collect(Collectors.toMap(DictDataRespDTO::getValue, DictDataRespDTO::getLabel));

        List<OrderRespVO> orderRespVOList = BeanUtils.toBean(list, OrderRespVO.class);

        for(OrderRespVO respVO : orderRespVOList){
            respVO.setStatusName(statusMap.get(respVO.getStatus()));
        }

        // 导出 Excel
        ExcelUtils.write(response, "生产订单信息.xls", "数据", OrderRespVO.class,
                orderRespVOList);
    }


    @GetMapping("/createPreparationByOrderCode")
    @Operation(summary = "根据生产订单生成备料单")
    public CommonResult<PageResult<PreparationVO>> createPreparationByOrderCode(@RequestParam Map<String, Object> params) {
        String orderCode = (String) params.get("orderCode");
        Object typeObj = params.get("type");

        if(null == typeObj || typeObj.toString().length() == 0){
            throw new ServiceException(ERROR_STATUS, "请选择规格型号");
        }

        String type = null;
        if(null != typeObj || typeObj.toString().length() > 0){
            type = typeObj.toString();
        }


        QueryWrapper<KisMaterielExWarehouseHistoryDO> kisMaterielExWarehouseHistoryDOQueryWrapper = new QueryWrapper<>();
        kisMaterielExWarehouseHistoryDOQueryWrapper.eq("order_code", orderCode);
        kisMaterielExWarehouseHistoryDOQueryWrapper.eq(!StringUtils.isEmpty(type), "type", type);
        Long count = kisMaterielExWarehouseHistoryMapper.selectCount(kisMaterielExWarehouseHistoryDOQueryWrapper);
        if (count > 0) {
            throw new ServiceException(ERROR_STATUS, "当前订单已出库,请勿重复出库");
        }

        // 如果当前订单状态是"未开始",则将其改成"进行中"
        OrderDO order = orderService.getOrder(orderCode);
        if (null == order) {
            QueryWrapper<KisMaterielExWarehouseDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("order_code", orderCode);
            queryWrapper.eq(!StringUtils.isEmpty(type), "type", type);
            List<KisMaterielExWarehouseDO> list = kisMaterielExWarehouseMapper.selectList(queryWrapper);

            List<PreparationVO> result = new ArrayList<>();

            for(KisMaterielExWarehouseDO kisMaterielExWarehouseDO : list){
                PreparationVO preparationVO = new PreparationVO();
                preparationVO.setOrderCode(orderCode);
                preparationVO.setType(kisMaterielExWarehouseDO.getType());
                preparationVO.setCode(kisMaterielExWarehouseDO.getCode());
                preparationVO.setMaterialStatus(kisMaterielExWarehouseDO.getMaterialStatus());
                preparationVO.setId(kisMaterielExWarehouseDO.getId());
                result.add(preparationVO);
            }

            PageResult<PreparationVO> preparationVOPageResult = new PageResult();
            preparationVOPageResult.setList(result);
            preparationVOPageResult.setTotal(Long.valueOf(result.size()));
            return success(preparationVOPageResult);

            //PageResult pageResult = new PageResult();
            //return success(pageResult);
        }
        if (null != order) {
            String status = order.getStatus();
            if (StringUtils.equals(status, ORDER_STATUS_0)) {
                order.setStatus(ORDER_STATUS_2);
                OrderSaveReqVO orderSaveReqVO = BeanUtils.toBean(order, OrderSaveReqVO.class);
                orderService.updateOrder(orderSaveReqVO);
            }
        }

        // 如果当前订单已经全部完成,则无需要备料
        Integer totalNum = order.getTotalNum().intValue();
        Integer totalExNum = kisMaterielExWarehouseHistoryMapper.selectExNumByOrderCode(params);
        if (null != totalExNum) {
            if (totalNum.compareTo(totalExNum) <= 0) {
                throw new ServiceException(ERROR_STATUS, "当前订单已经全部完成,无须再领料");
            }
        }

        List<PreparationVO> preparationVOS = orderService.createPreparationByOrderCode(params);
        if (CollectionUtil.isNotEmpty(preparationVOS)) {

            List<OrderFlexNumVO> orderFlexNumVOS = orderService.selectTypeNumByOrderCode(params);
            Integer exBatch = kisMaterielExWarehouseHistoryMapper.selectExCodeNumByOrderCode(params);
            // Long exBatch = kisMaterielExWarehouseHistoryMapper.selectCount("distinct order_code", orderCode);
            String serialNumber = SERIAL_NUMBER_INIT + (exBatch + 1);
            String formatSerialNumber = serialNumber.substring(serialNumber.length() - (SERIAL_NUMBER_INIT.length() + 1));

            String exCode = "CK" + orderCode + "_" + formatSerialNumber;

            List<KisMaterielExWarehouseDO> tempList = kisMaterielExWarehouseMapper.selectList(new QueryWrapper<KisMaterielExWarehouseDO>().eq("order_code", orderCode).orderByDesc("ex_code"));

            if(tempList != null && tempList.size() > 0){
                KisMaterielExWarehouseDO tempKisMaterielExWarehouseDO = tempList.get(0);
                exCode = tempKisMaterielExWarehouseDO.getExCode();
                exCode = exCode.substring(0, exCode.length() - 1) + (Integer.parseInt(exCode.substring(exCode.length() - 1)) + 1);
            }

            List<KisMaterielExWarehouseDO> importDataList = new ArrayList<>();
            for (PreparationVO preparationVO : preparationVOS) {
                // String orderCode = preparationVO.getOrderCode();
                String typeStr = preparationVO.getType();
                preparationVO.setExCode(exCode);
                String code = preparationVO.getCode();
                String specification = preparationVO.getSpecification();
                KisMaterielExWarehouseDO kisMaterielExWarehouseDO = new KisMaterielExWarehouseDO();
                kisMaterielExWarehouseDO.setOrderCode(orderCode);
                kisMaterielExWarehouseDO.setType(typeStr);
                kisMaterielExWarehouseDO.setCode(code);
                kisMaterielExWarehouseDO.setId(orderCode + "_" + typeStr + "_" + code + "_" + formatSerialNumber);
                kisMaterielExWarehouseDO.setExCode(exCode);
                kisMaterielExWarehouseDO.setSpecification(specification);
                importDataList.add(kisMaterielExWarehouseDO);

                if (CollectionUtil.isNotEmpty(orderFlexNumVOS)) {
                    for (OrderFlexNumVO orderFlexNumVO : orderFlexNumVOS) {
                        if (StringUtils.equals(type, orderFlexNumVO.getType())) {
                            kisMaterielExWarehouseDO.setCodeNum(orderFlexNumVO.getNum());
                        }
                    }
                }

            }
            List<String> ids = importDataList.stream()
                    .map(c -> {
                        return c.getId();
                    })
                    .distinct()
                    .collect(Collectors.toList());
            //Map<String, Object> param = new HashMap<>();
            params.put("ids", ids);

            // 查询已经存在的物料单数据,这些将不再写入库中
            List<KisMaterielExWarehouseDO> savedList = kisMaterielExWarehouseService.selectSavedList(params);
            List<KisMaterielExWarehouseDO> updateList = new ArrayList<KisMaterielExWarehouseDO>();
            List<KisMaterielExWarehouseDO> insertList = new ArrayList<KisMaterielExWarehouseDO>();

            for (KisMaterielExWarehouseDO record : importDataList) {
                boolean issaved = false;

                if (null != savedList && savedList.size() > 0) {
                    for (KisMaterielExWarehouseDO saved : savedList) {
                        if (
                                saved.getId().equals(record.getId())
                        ) {
                            record.setDeleted(false);
                            record.setId(saved.getId());
                            updateList.add(record);
                            issaved = true;
                            break;
                        }
                    }

                }

                if (!issaved) {
                    record.setDeleted(false);
                    insertList.add(record);
                }
            }


            // kisMaterielExWarehouseService.updateRecord(updateList);

            Map<String, Object> map = new HashMap<>();
            map.put("orderCode", orderCode);
            map.put("type", type);
            List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectLastExCodeByOrderCode(map);

            if(null == kisMaterielExWarehouseDOS || kisMaterielExWarehouseDOS.size() == 0){
                kisMaterielExWarehouseService.insertRecord(insertList);
            }


            preparationVOS = BeanUtils.toBean(kisMaterielExWarehouseDOS, PreparationVO.class);
        }

        Integer pageNo = 1;
        Integer pageSize = 10;
        Object pageNoObj = params.get("pageNo");
        Object pageSizeObj = params.get("pageSize");
        if (null != pageNoObj) {
            if (NumberUtil.isNumber(pageNoObj.toString())) {
                pageNo = Integer.valueOf(pageNoObj.toString());
            }
        }
        if (null != pageSizeObj) {
            if (NumberUtil.isNumber(pageSizeObj.toString())) {
                pageSize = Integer.valueOf(pageSizeObj.toString());
            }
        }

        int size = preparationVOS.size();
        PageResult<PreparationVO> preparationVOPageResult = new PageResult<>();
        preparationVOPageResult.setTotal(Long.valueOf(size));
        if (CollectionUtil.isNotEmpty(preparationVOS)) {
            List<PreparationVO> collect = preparationVOS.stream()
                    .skip((pageNo - 1) * pageSize) // 跳过前面的元素
                    .limit(pageSize) // 限制输出的元素数量
                    .collect(Collectors.toList());
            preparationVOPageResult.setList(collect);
        }
        return success(preparationVOPageResult);
    }


    @GetMapping("/getMaterialByOrderCode")
    @Operation(summary = "根据生产订单获取领料单")
    public CommonResult<PageResult<PreparationVO>> getMaterialByOrderCode(@RequestParam Map<String, Object> params) {
        String orderCode = (String) params.get("orderCode");
        // 根据订单编号查询不在审核状态下的物料数量,如果有物料不在审核状态,则不允许领料
        Integer count = kisMaterielExWarehouseService.selectUncheckMaterialByOrderCode(params);
        if (null != count && count > 0) {
            throw new ServiceException(ERROR_STATUS, "该生产订单有" + count + "条数据不在审核状态");
        }

        // 领料只查看待审核状态的物料,不查看已审核状态的物料
        QueryWrapper<KisMaterielExWarehouseDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_code", orderCode);
        queryWrapper.eq("material_status", MATERIAL_STATUS_2);
        List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList(queryWrapper);
        List<PreparationVO> preparationVOS = BeanUtils.toBean(kisMaterielExWarehouseDOS, PreparationVO.class);

        // 忽略已经提交过的物料,不用再次提交
        if (CollectionUtil.isNotEmpty(preparationVOS)) {
            preparationVOS = preparationVOS.stream()
                    .filter(c -> StringUtils.equals(SUBMIT_STATUS_0,c.getSubmitStatus()))
                    .collect(Collectors.toList());
        }

        Integer pageNo = 1;
        Integer pageSize = 10;
        Object pageNoObj = params.get("pageNo");
        Object pageSizeObj = params.get("pageSize");
        if (null != pageNoObj) {
            if (NumberUtil.isNumber(pageNoObj.toString())) {
                pageNo = Integer.valueOf(pageNoObj.toString());
            }
        }
        if (null != pageSizeObj) {
            if (NumberUtil.isNumber(pageSizeObj.toString())) {
                pageSize = Integer.valueOf(pageSizeObj.toString());
            }
        }

        int size = preparationVOS.size();
        PageResult<PreparationVO> preparationVOPageResult = new PageResult<>();
        preparationVOPageResult.setTotal(Long.valueOf(size));
        if (CollectionUtil.isNotEmpty(preparationVOS)) {
            List<PreparationVO> collect = preparationVOS.stream()
                    // .skip((pageNo - 1) * pageSize) // 跳过前面的元素
                    // .limit(pageSize) // 限制输出的元素数量
                    .collect(Collectors.toList());
            preparationVOPageResult.setList(collect);
        }
        return success(preparationVOPageResult);
    }

    @GetMapping("/getbindBoxCode")
    @Operation(summary = "根据生产订单获取领料单")
    public CommonResult<PageResult<PreparationVO>> getbindBoxCode(@RequestParam Map<String, Object> params) {
        String orderCode = (String) params.get("orderCode");
        String flex = (String)params.get("flex");
        // 根据订单编号查询不在审核状态下的物料数量,如果有物料不在审核状态,则不允许领料
        Integer count = kisMaterielExWarehouseService.selectUncheckMaterialByOrderCode(params);
        if (null != count && count > 0) {
            throw new ServiceException(ERROR_STATUS, "该生产订单有" + count + "条数据不在审核状态");
        }

        // 领料只查看待审核状态的物料,不查看已审核状态的物料
        QueryWrapper<KisMaterielExWarehouseDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_code", orderCode);
        queryWrapper.eq("type", flex);
        queryWrapper.eq("material_status", MATERIAL_STATUS_2);
        List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList(queryWrapper);
        List<PreparationVO> preparationVOS = BeanUtils.toBean(kisMaterielExWarehouseDOS, PreparationVO.class);

        // 忽略已经提交过的物料,不用再次提交
        if (CollectionUtil.isNotEmpty(preparationVOS)) {
            preparationVOS = preparationVOS.stream()
                    .filter(c -> StringUtils.equals(SUBMIT_STATUS_0,c.getSubmitStatus()))
                    .collect(Collectors.toList());
        }

        Integer pageNo = 1;
        Integer pageSize = 10;
        Object pageNoObj = params.get("pageNo");
        Object pageSizeObj = params.get("pageSize");
        if (null != pageNoObj) {
            if (NumberUtil.isNumber(pageNoObj.toString())) {
                pageNo = Integer.valueOf(pageNoObj.toString());
            }
        }
        if (null != pageSizeObj) {
            if (NumberUtil.isNumber(pageSizeObj.toString())) {
                pageSize = Integer.valueOf(pageSizeObj.toString());
            }
        }

        int size = preparationVOS.size();
        PageResult<PreparationVO> preparationVOPageResult = new PageResult<>();
        preparationVOPageResult.setTotal(Long.valueOf(size));
        if (CollectionUtil.isNotEmpty(preparationVOS)) {
            List<PreparationVO> collect = preparationVOS.stream()
                    // .skip((pageNo - 1) * pageSize) // 跳过前面的元素
                    // .limit(pageSize) // 限制输出的元素数量
                    .collect(Collectors.toList());
            preparationVOPageResult.setList(collect);
        }
        return success(preparationVOPageResult);
    }

    @GetMapping("/getExCodeByOrderCode")
    @Operation(summary = "根据生产订单获取领料单列表")
    public CommonResult<List<String>> getExCodeByOrderCode(@RequestParam Map<String, Object> params) {
        String orderCode = (String) params.get("orderCode");
        List<String> exCodeByOrderCode = null;
        try {
            Assert.notNull(orderCode, "订单编号不能为空");
            exCodeByOrderCode = kisMaterielExWarehouseMapper.getExCodeByOrderCode(params);
        }
        catch (IllegalArgumentException e) {
            throw new ServiceException(ERROR_STATUS, e.getMessage());
        }
        catch (Exception e) {

        }

        return success(exCodeByOrderCode);
    }

    @GetMapping("/getHisMaterialByOrderCode")
    @Operation(summary = "根据生产订单获取已审核通过的领料单")
    public CommonResult<PageResult<PreparationVO>> getHisMaterialByOrderCode(@RequestParam Map<String, Object> params) {
        // String orderCode = (String) params.get("orderCode");
        String exCode = (String) params.get("exCode");

        // 领料只查看已审核状态的物料
        QueryWrapper<KisMaterielExWarehouseDO> queryWrapper = new QueryWrapper<>();
        // queryWrapper.eq("order_code", orderCode);
        queryWrapper.eq("material_status", MATERIAL_STATUS_1);
        if (StringUtils.isNotBlank(exCode)) {
            queryWrapper.eq("ex_code", exCode);
        }
        List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList(queryWrapper);
        List<PreparationVO> preparationVOS = BeanUtils.toBean(kisMaterielExWarehouseDOS, PreparationVO.class);

        Integer pageNo = 1;
        Integer pageSize = 10;
        Object pageNoObj = params.get("pageNo");
        Object pageSizeObj = params.get("pageSize");
        if (null != pageNoObj) {
            if (NumberUtil.isNumber(pageNoObj.toString())) {
                pageNo = Integer.valueOf(pageNoObj.toString());
            }
        }
        if (null != pageSizeObj) {
            if (NumberUtil.isNumber(pageSizeObj.toString())) {
                pageSize = Integer.valueOf(pageSizeObj.toString());
            }
        }

        int size = preparationVOS.size();
        PageResult<PreparationVO> preparationVOPageResult = new PageResult<>();
        preparationVOPageResult.setTotal(Long.valueOf(size));
        if (CollectionUtil.isNotEmpty(preparationVOS)) {
            List<PreparationVO> collect = preparationVOS.stream()
                    .skip((pageNo - 1) * pageSize) // 跳过前面的元素
                    .limit(pageSize) // 限制输出的元素数量
                    .collect(Collectors.toList());
            preparationVOPageResult.setList(collect);
        }
        return success(preparationVOPageResult);
    }


    @PostMapping("/createInternalCodeByOrderCode")
    @Operation(summary = "根据生产订单生成内码")
    public CommonResult<Boolean> createInternalCodeByOrderCode(@RequestBody PreparationVO reqVO) {
        kisMaterielExWarehouseService.createInternalCodeByOrderCode(reqVO);
        return success(true);
    }

    @PostMapping("/checkExCodeStatus")
    @Operation(summary = "根据生产订单检查物料单是否全部审核通过")
    public CommonResult<Boolean> checkExCodeStatus(@RequestBody PreparationVO reqVO) {
        String orderCode = reqVO.getOrderCode();
        if (StringUtils.isBlank(orderCode)) {
            return success(false);
        }
        String type = reqVO.getType();
        if(StringUtils.isEmpty(type)){
            return success(false);
        }

        Map<String, Object> param = new HashMap<>();
        param.put("orderCode", orderCode);
        param.put("type", type);

        // 根据订单编号查询最近的物料单,如果物料单中有物料审核状态未通过,则提示
        List<KisMaterielExWarehouseDO> lastExCodeList = kisMaterielExWarehouseService.selectLastExCodeByOrderCode(param);
        if (CollectionUtil.isNotEmpty(lastExCodeList)) {
            List<KisMaterielExWarehouseDO> uncheckList = lastExCodeList.stream()
                    .filter(c -> !StringUtils.equals(MATERIAL_STATUS_1, c.getMaterialStatus()))
                    .collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(uncheckList)) {
                return success(false);
            }
            if (!CollectionUtil.isNotEmpty(uncheckList)) {
                return success(true);
            }
        }
        return success(false);
    }


    @PostMapping("/createBatchInternalCode")
    @Operation(summary = "根据生产订单批量提交物料出库单")
    public CommonResult<Boolean> createBatchInternalCode(@RequestBody List<PreparationVO> reqVO) {
        if (CollectionUtil.isNotEmpty(reqVO)) {
            // 获取第一个元素,根据订单编号查询各型号
            PreparationVO preparationVO1 = reqVO.get(0);
            String orderCode = preparationVO1.getOrderCode();
            Map<String, Object> param = new HashMap<>();
            param.put("orderCode", orderCode);
            List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseService.selectTypeByOrderCode(param);
            if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS)) {
                for (KisMaterielExWarehouseDO kisMaterielExWarehouseDO : kisMaterielExWarehouseDOS) {
                    String exCode = kisMaterielExWarehouseDO.getExCode();
                    String type = kisMaterielExWarehouseDO.getType();
                    Integer startNum = 0;
                    Map<String, Object> exNumParam = new HashMap<>();
                    exNumParam.put("orderCode", orderCode);
                    exNumParam.put("type", type);
                    // Integer exNum = kisMaterielExWarehouseHistoryMapper.selectExNumByOrderCodeAndType(exNumParam);
                    Integer exNum = kisMaterielExWarehouseHistoryMapper.selectExNumByExCode(exNumParam);
                    if (null != exNum) {
                        startNum = exNum;
                    }

                    List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS1 = kisMaterielExWarehouseService.selectLastExCodeByOrderCode(param);
                    if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS1)) {
                        for (KisMaterielExWarehouseDO materielExWarehouseDO : kisMaterielExWarehouseDOS1) {
                            String id = materielExWarehouseDO.getId();
                            String code = materielExWarehouseDO.getCode();
                            String cartonCode = materielExWarehouseDO.getCartonCode();
                            String cartonJson = materielExWarehouseDO.getCartonJson();
                            Integer codeNum = materielExWarehouseDO.getCodeNum();
                            // 如果箱码是单个
                            if (StringUtils.isNotBlank(cartonCode) && !cartonCode.contains(",")) {
                                int num = codeNum - startNum;
                                if (StringUtils.isBlank(cartonJson)) {
                                    List<CartonCodeDetailNumVO> cartonCodeDetailNumVOS = new ArrayList<>();
                                    CartonCodeDetailNumVO cartonCodeDetailNumVO = new CartonCodeDetailNumVO();
                                    cartonCodeDetailNumVO.setId(id);
                                    cartonCodeDetailNumVO.setOrderCode(orderCode);
                                    cartonCodeDetailNumVO.setType(type);
                                    cartonCodeDetailNumVO.setCode(code);
                                    cartonCodeDetailNumVO.setCartonCode(cartonCode);
                                    cartonCodeDetailNumVO.setExCode(exCode);
                                    cartonCodeDetailNumVO.setNum(num);
                                    cartonCodeDetailNumVOS.add(cartonCodeDetailNumVO);
                                    String updateCartonJson = JsonUtils.toJsonString(cartonCodeDetailNumVOS);

                                    KisMaterielExWarehouseDO kisMaterielExWarehouseDO1 = new KisMaterielExWarehouseDO();
                                    kisMaterielExWarehouseDO1.setId(id);
                                    kisMaterielExWarehouseDO1.setCartonJson(updateCartonJson);
                                    kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO1);
                                }
                            }
                        }
                    }

                }
            }

            // 将当前提交的所有物料的pda提交状态改成已提交
            for (PreparationVO preparationVO : reqVO) {
                String id = preparationVO.getId();
                KisMaterielExWarehouseDO kisMaterielExWarehouseDO = new KisMaterielExWarehouseDO();
                kisMaterielExWarehouseDO.setId(id);
                kisMaterielExWarehouseDO.setSubmitStatus(SUBMIT_STATUS_1);
                kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO);
            }
        }
        return success(true);
    }

    @PostMapping("/bindBoxCodeSave")
    @Operation(summary = "根据生产订单批量提交物料出库单")
    public CommonResult<Boolean> bindBoxCodeSave(@RequestBody List<PreparationVO> reqVO) {
        if (CollectionUtil.isNotEmpty(reqVO)) {
            // 获取第一个元素,根据订单编号查询各型号
            PreparationVO preparationVO1 = reqVO.get(0);
            String orderCode = preparationVO1.getOrderCode();
            String type = preparationVO1.getType();
            Map<String, Object> param = new HashMap<>();
            param.put("orderCode", orderCode);
            param.put("type", type);
            List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseService.selectTypeByOrderCode(param);
            if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS)) {
                for (KisMaterielExWarehouseDO kisMaterielExWarehouseDO : kisMaterielExWarehouseDOS) {
                    String exCode = kisMaterielExWarehouseDO.getExCode();
                    type = kisMaterielExWarehouseDO.getType();
                    Integer startNum = 0;
                    Map<String, Object> exNumParam = new HashMap<>();
                    exNumParam.put("orderCode", orderCode);
                    exNumParam.put("type", type);
                    Integer exNum = kisMaterielExWarehouseHistoryMapper.selectExNumByExCode(exNumParam);
                    if (null != exNum) {
                        startNum = exNum;
                    }

                    List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS1 = kisMaterielExWarehouseService.selectLastExCodeByOrderCode(param);
                    if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS1)) {
                        for (KisMaterielExWarehouseDO materielExWarehouseDO : kisMaterielExWarehouseDOS1) {
                            String id = materielExWarehouseDO.getId();
                            String code = materielExWarehouseDO.getCode();
                            String cartonCode = materielExWarehouseDO.getCartonCode();
                            String cartonJson = materielExWarehouseDO.getCartonJson();
                            Integer codeNum = materielExWarehouseDO.getCodeNum();
                            // 如果箱码是单个
                            if (StringUtils.isNotBlank(cartonCode) && !cartonCode.contains(",")) {
                                int num = codeNum - startNum;
                                if (StringUtils.isBlank(cartonJson)) {
                                    List<CartonCodeDetailNumVO> cartonCodeDetailNumVOS = new ArrayList<>();
                                    CartonCodeDetailNumVO cartonCodeDetailNumVO = new CartonCodeDetailNumVO();
                                    cartonCodeDetailNumVO.setId(id);
                                    cartonCodeDetailNumVO.setOrderCode(orderCode);
                                    cartonCodeDetailNumVO.setType(type);
                                    cartonCodeDetailNumVO.setCode(code);
                                    cartonCodeDetailNumVO.setCartonCode(cartonCode);
                                    cartonCodeDetailNumVO.setExCode(exCode);
                                    cartonCodeDetailNumVO.setNum(num);
                                    cartonCodeDetailNumVOS.add(cartonCodeDetailNumVO);
                                    String updateCartonJson = JsonUtils.toJsonString(cartonCodeDetailNumVOS);

                                    KisMaterielExWarehouseDO kisMaterielExWarehouseDO1 = new KisMaterielExWarehouseDO();
                                    kisMaterielExWarehouseDO1.setId(id);
                                    kisMaterielExWarehouseDO1.setCartonJson(updateCartonJson);
                                    kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO1);
                                }
                            }
                        }
                    }

                }
            }

            // 将当前提交的所有物料的pda提交状态改成已提交
            for (PreparationVO preparationVO : reqVO) {
                String id = preparationVO.getId();
                KisMaterielExWarehouseDO kisMaterielExWarehouseDO = new KisMaterielExWarehouseDO();
                kisMaterielExWarehouseDO.setId(id);
                kisMaterielExWarehouseDO.setSubmitStatus(SUBMIT_STATUS_1);
                kisMaterielExWarehouseMapper.updateById(kisMaterielExWarehouseDO);
            }
        }
        return success(true);
    }


}
